/**
 * 使用 基于 better-scroll   
 *  需引入 better-scroll 插件
 *  scrollY:false,scrollX:true,默认 x 轴方向滚动
 *  子元素排列 不要用margin ，用padding，（子元素里可以再插入一个子元素）
 *   1  new NavScroll('.table-wrapper') 
       2. var nav = new NavScroll('.nav-wrapper',{
                scrollY:true,
                scrollX:false,
            })
         nav.on('click',function({oldIndex,index}){
                console.log({oldIndex,index})
            })
    效果  对index+1  或 index-1  元素 预滚动出来        
 */
import EventEmitter from "./eventEmitter"
import BScroll from "better-scroll"
export default class NavScroll extends EventEmitter {
    constructor(wrapper, options){
        super()
        if( wrapper.nodeType === 1){
            this.wrapperEl = wrapper
        }else{
            this.wrapperEl = document.getElementsByClassName(wrapper)[0]
            if (!this.wrapperEl) return console.log('wrapper 节点不存在')
        }
        var child = this.wrapperEl.firstElementChild
        this.options = {
            scrollX: true,
            scrollY: false,
            click: true,
            probeType: 3
        }
        this._extend(options)
        this._init()
    }
    _typeOf(o){
        return ({}).toString.call(o).match(/\[object (.*?)\]/)[1].toLowerCase();        
    }
    _extend(options){
        let type = this._typeOf(options)
        if (type !== 'object') return
        for (var key in options) {
                this.options[key] = options[key];
        }
    }
    _addEvent(el,type,fn){
        el.addEventListener(type, fn, {passive:false,capture:false});        
    }
    _findParent(el,flag){
        if(el.isParent) return el
        if(el === flag) return null
        return this._findParent(el.parentNode,flag)
    }
    _init(){
        this.wrapperX = this.wrapperEl.offsetWidth
        this.wrapperY = this.wrapperEl.offsetHeight
        this.navArr = this.wrapperEl.firstElementChild.children
        if (!this.navArr.length) return
        this.index = 0
        this._initOffset(this.navArr)
        this._initScroll()
        this._bindEvent()
        return this
    }
    _initScroll(){
        if (this.scroll) return this.scroll.refresh()
        this.scroll = new BScroll(this.wrapperEl, this.options)
    }
    _initOffset (arr) {
        if (!arr) {
            var arr = this.wrapperEl.firstElementChild.children
        }
        var l = arr.length
        var sum = 0
        this.offsetArr = [0]
        var scrollX = this.options.scrollX
        for (var i = 0; i < l; i++) {
            if (scrollX) {
                if (!this.Max && (sum < this.wrapperX && (sum + arr[i].offsetWidth) >= this.wrapperX)) {
                    this.Max = sum
                }
                sum += arr[i].offsetWidth
            } else {
                if (!this.Max && (sum < this.wrapperY && (sum + arr[i].offsetHeight) >= this.wrapperY)) {
                    this.Max = sum
                }
                sum += arr[i].offsetHeight
            }
            arr[i].isParent = true
            this.offsetArr.push(sum)
        }
        if (scrollX) {
            arr[0].parentNode.style.width = sum + 'px'
        } else {
            arr[0].parentNode.style.height = sum + 'px'
        }
    }
    _bindEvent () {
        var el = this.wrapperEl
        var _this = this
        this._addEvent(el, 'click', function (e) {
            e.stopPropagation()
            var nav = _this._findParent(e.target,el)
            if(!nav) return
            var index = [].indexOf.call(_this.navArr,nav)
            if(index === -1) return
            _this.trigger('click', {
                oldIndex: _this.index,
                index: index
            })
            _this.index = index
            _this._scrollTo(index)
        })
    }
    _scrollTo (index) {
        var length = this.navArr.length,
            oArr = this.offsetArr,
            wrapperX = this.wrapperX,
            wrapperY = this.wrapperY,
            navArr = this.navArr,
            scroll = this.scroll,
            scrollX = this.options.scrollX,
            Max = this.Max,
            x = 0,
            y = 0;
        switch (true) {
            // 长度不够
            case (oArr[length] <= wrapperX || oArr[length] <= wrapperY):
                break;
                //点击 第一个时
            case (index === 0):
                scroll.scrollToElement(navArr[index], 200)
                break;
                //点击 最后一个时
            case (index === (length - 1)):
                scroll.scrollToElement(navArr[index], 200)
                break;
                // 判断 index-1 
            case ((oArr[index - 1] <= Math.abs(scroll.x)) || (oArr[index - 1] <= Math.abs(scroll.y))):
                scroll.scrollToElement(navArr[index - 1], 200)
                break;
                // x方向 index+1
            case (scrollX && (oArr[index + 2] > (Max - scroll.x))):
                x = oArr[index + 2] - wrapperX
                scroll.scrollTo(-x, 0, 200)
                break;
                // y方向 index+1
            case (!scrollX && (oArr[index + 2] > (Max - scroll.y))):
                y = oArr[index + 2] - wrapperY
                scroll.scrollTo(0, -y, 200)
                break;
            default:
                break;
        }
    }
    scrollToIndex (index) {
        var el = this.navArr[index]
        if (!el) return
        this.scroll.scrollToElement(el, 200)
        return this
    }
    refresh () {
        this._initOffset()
        this.scroll.refresh()
        this.scrollToIndex(0)
        return this
    }
}
// (function () {
        
//             var EventEmitter = function () {
//                 this._events = {};
//             }
//             EventEmitter.prototype = {
//                 on: function (type, fn, context) {
//                     if (!context) {
//                         context = this
//                     }
//                     if (!this._events[type]) {
//                         this._events[type] = [];
//                     }
//                     this._events[type].push([fn, context]);
//                 },
//                 once: function (type, fn, context) {
//                     if (!context) {
//                         context = this
//                     }
//                     var fired = false;
        
//                     function magic() {
//                         this.off(type, magic);
        
//                         if (!fired) {
//                             fired = true;
//                             fn.apply(context, arguments);
//                         }
//                     }
        
//                     this.on(type, magic);
//                 },
        
//                 off: function (type, fn) {
//                     var _events = this._events[type];
//                     if (!_events) {
//                         return;
//                     }
        
//                     var count = _events.length;
//                     while (count--) {
//                         if (_events[count][0] === fn) {
//                             _events[count][0] = undefined;
//                         }
//                     }
//                 },
//                 trigger: function (type) {
//                     var events = this._events[type];
//                     if (!events) {
//                         return;
//                     }
//                     var len = events.length;
//                     var eventsCopy = [].slice.call(events)
//                     for (var i = 0; i < len; i++) {
//                         (function (i, arg) {
//                             var event = eventsCopy[i];
//                             var fn = event[0]
//                             var context = event[1]
//                             if (fn) {
//                                 fn.apply(context, [].slice.call(arg, 1));
//                             }
//                         })(i, arguments)
//                     }
//                 }
//             }
//             var NavScroll = function (wrapper, options) {
//                 this.wrapperEl = document.querySelector(wrapper)
//                 if (!this.wrapperEl) return console.log('wrapper 节点不存在')
//                 var child = this.wrapperEl.firstElementChild
//                 this.options = {
//                     scrollX: true,
//                     scrollY: false,
//                     click: true,
//                     probeType: 3
//                 }
//                 this._extend(options)
//                 EventEmitter.call(this)
//                 this._init()
//             }
        
//             NavScroll.prototype = new EventEmitter()
//             NavScroll.prototype.constructor = NavScroll
//             NavScroll.prototype._typeOf = function (o) {
//                 return ({}).toString.call(o).match(/\[object (.*?)\]/)[1].toLowerCase();
//             }
//             NavScroll.prototype._extend = function (options) {
//                 var type = this._typeOf(options)
//                 if (type !== 'object') return
//                 for (var key in options) {
//                         this.options[key] = options[key];
//                 }
//             }
//             NavScroll.prototype._addEvent = function (el, type, fn) {
//                 el.addEventListener(type, fn, {passive:false,capture:false});
//             }
//             NavScroll.prototype.findParent = function(el,flag){
//                 if(el.isParent) return el
//                 if(el === flag) return null
//                 return arguments.callee(el.parentNode,flag)
//             }
//             NavScroll.prototype._init = function () {
//                 this.wrapperX = this.wrapperEl.offsetWidth
//                 this.wrapperY = this.wrapperEl.offsetHeight
//                 this.navArr = this.wrapperEl.firstElementChild.children
//                 if (!this.navArr.length) return
//                 this.index = 0
//                 this._initOffset(this.navArr)
//                 this._initScroll()
//                 this._bindEvent()
//                 return this
//             }
//             NavScroll.prototype._initScroll = function () {
//                 if (this.scroll) return this.scroll.refresh()
//                 this.scroll = new BScroll(this.wrapperEl, this.options)
//             }
        
//             NavScroll.prototype._initOffset = function (arr) {
//                 if (!arr) {
//                     var arr = this.wrapperEl.firstElementChild.children
//                 }
//                 var l = arr.length
//                 var sum = 0
//                 this.offsetArr = [0]
//                 var scrollX = this.options.scrollX
//                 for (var i = 0; i < l; i++) {
//                     if (scrollX) {
//                         if (!this.Max && (sum < this.wrapperX && (sum + arr[i].offsetWidth) >= this.wrapperX)) {
//                             this.Max = sum
//                         }
//                         sum += arr[i].offsetWidth
//                     } else {
//                         if (!this.Max && (sum < this.wrapperY && (sum + arr[i].offsetHeight) >= this.wrapperY)) {
//                             this.Max = sum
//                         }
//                         sum += arr[i].offsetHeight
//                     }
//                     arr[i].isParent = true
//                     this.offsetArr.push(sum)
//                 }
//                 if (scrollX) {
//                     arr[0].parentNode.style.width = sum + 'px'
//                 } else {
//                     arr[0].parentNode.style.height = sum + 'px'
//                 }
//             }
        
//             NavScroll.prototype._bindEvent = function () {
//                 var el = this.wrapperEl
//                 var _this = this
//                 this._addEvent(el, 'click', function (e) {
//                     e.stopPropagation()
//                     var nav = _this.findParent(e.target,el)
//                     if(!nav) return
//                     var index = [].indexOf.call(_this.navArr,nav)
//                     if(index === -1) return
//                     _this.trigger('click', {
//                         oldIndex: _this.index,
//                         index: index
//                     })
//                     _this.index = index
//                     _this._scrollTo(index)
//                 })
//             }
        
//             NavScroll.prototype._scrollTo = function (index) {
//                 var length = this.navArr.length,
//                     oArr = this.offsetArr,
//                     wrapperX = this.wrapperX,
//                     wrapperY = this.wrapperY,
//                     navArr = this.navArr,
//                     scroll = this.scroll,
//                     scrollX = this.options.scrollX,
//                     Max = this.Max,
//                     x = 0,
//                     y = 0;
//                 switch (true) {
//                     // 长度不够
//                     case (oArr[length] <= wrapperX || oArr[length] <= wrapperY):
//                         break;
//                         //点击 第一个时
//                     case (index === 0):
//                         scroll.scrollToElement(navArr[index], 200)
//                         break;
//                         //点击 最后一个时
//                     case (index === (length - 1)):
//                         scroll.scrollToElement(navArr[index], 200)
//                         break;
//                         // 判断 index-1 
//                     case ((oArr[index - 1] <= Math.abs(scroll.x)) || (oArr[index - 1] <= Math.abs(scroll.y))):
//                         scroll.scrollToElement(navArr[index - 1], 200)
//                         break;
//                         // x方向 index+1
//                     case (scrollX && (oArr[index + 2] > (Max - scroll.x))):
//                         x = oArr[index + 2] - wrapperX
//                         scroll.scrollTo(-x, 0, 200)
//                         break;
//                         // y方向 index+1
//                     case (!scrollX && (oArr[index + 2] > (Max - scroll.y))):
//                         y = oArr[index + 2] - wrapperY
//                         scroll.scrollTo(0, -y, 200)
//                         break;
//                     default:
//                         break;
//                 }
//             }
//             NavScroll.prototype.scrollToIndex = function (index) {
//                 var el = this.navArr[index]
//                 if (!el) return
//                 this.scroll.scrollToElement(el, 200)
//                 return this
//             }
//             //刷新 navArr
//             NavScroll.prototype.refresh = function () {
//                 this._initOffset()
//                 this.scroll.refresh()
//                 this.scrollToIndex(0)
//                 return this
//             }
// })()
